#ifndef RUNTEST_H
#define RUNTEST_H


#include "CorrelationParent.h"
#include "Correlation.h"
#include "Data.h"
#include "test/Test.h"


/*
  This class contains test cases for the correlation class. Having these functions in a separate class improves code
    organization.

  Each member function of the runTest class simply executes comparisons and keeps track of successes and failures. This
    is done with the help of the test object. In general, no initialization of test object, resetting the test members
    sCount and fCount, or calling test::reportStatus() is allowed. These actions are handled by the main() function.
  */
class RunTest : public CorrelationParent {


public:  // Non-Correlation tests


    /* ----- Test Class Test ---------------------------------------------------------------------------------------- */

    // Constructor, getters/setters, other functions related purely to the class implementation
    void testTest(int whichTest, Correlation *c, Data *d, Test *t);


    /* ----- Class Implementation Functions ------------------------------------------------------------------------- */

    void correlationConstructor(int whichTest, Correlation *c, Data *d, Test *t);


public:  // Correlation-specific tests


    /* ----- Level 0 Functions -------------------------------------------------------------------------------------- */

    bool analyzeImage(int whichTest, Correlation *c, Data *d, Test *t);
    void storePositionField(int whichTest, Correlation *c, Data *d, Test *t);
    void storeStrainField(int whichTest, Correlation *c, Data *d, Test *t);
    void outputImage(int whichTest, Correlation *c, Data *d, Test *t);
    void outputOverlay(int whichTest, Correlation *c, Data *d, Test *t);


    /* ----- Level 1 Functions -------------------------------------------------------------------------------------- */

    void loadPersistentValues(int whichTest, Correlation *c, Data *d, Test *t);
    void savePersistentValues(int whichTest, Correlation *c, Data *d, Test *t);
    bool inputImage(int whichTest, Correlation *c, Data *d, Test *t);
    void blobAnalysis(int whichTest, Correlation *c, Data *d, Test *t);
    void extractPositionField(int whichTest, Correlation *c, Data *d, Test *t);
    void generateGridMap(int whichTest, Correlation *c, Data *d, Test *t);
    void computeStrain(int whichTest, Correlation *c, Data *d, Test *t);
    void drawCurrentState(int whichTest, Correlation *c, Data *d, Test *t);


    /* ----- Level 2 Functions -------------------------------------------------------------------------------------- */

    void subsetImage(int whichTest, Correlation *c, Data *d, Test *t);
    void filterImage(int whichTest, Correlation *c, Data *d, Test *t);
    void matchBlob(int whichTest, Correlation *c, Data *d, Test *t);
    void updateBoundingBox(int whichTest, Correlation *c, Data *d, Test *t);
    void mergeBlobs(int whichTest, Correlation *c, Data *d, Test *t);
    void postProcess(int whichTest, Correlation *c, Data *d, Test *t);
    void blobProbability(int whichTest, Correlation *c, Data *d, Test *t);
    void identifyDots(int whichTest, Correlation *c, Data *d, Test *t);
    void isValidPointSet(int whichTest, Correlation *c, Data *d, Test *t);
    void localStrain(int whichTest, Correlation *c, Data *d, Test *t);
    double minAbs(int whichTest, Correlation *c, Data *d, Test *t);
    double maxAbs(int whichTest, Correlation *c, Data *d, Test *t);
    void minIgnore(int whichTest, Correlation *c, Data *d, Test *t);
    void maxIgnore(int whichTest, Correlation *c, Data *d, Test *t);
    void drawBlobProperty(int whichTest, Correlation *c, Data *d, Test *t);
    void drawCurrentPixel(int whichTest, Correlation *c, Data *d, Test *t);
    void debugHandle(int whichTest, Correlation *c, Data *d, Test *t);


private:  // Internal functions


public:  // Non-derived parameters


    /* ----- RunTest Class Variables -------------------------------------------------------------------------------- */

    string pathNames[1001];
    string fileNames[1000];

    // Global test result tracking. Useful for bulk tests.
    int sCountGlobal, fCountGlobal;

    // Absolute tolerances for comparisons
    double positionTol, strainTol;

    // temp
    double maxPError;


};

#endif // RUNTEST_H
